package com.hj.aiagent.tools;

import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 终端操作工具
 * @author 黄健
 */
public class TerminalOperationTool {

    /**
     * 在终端中执行指定命令，并返回命令执行结果。
     *
     * @param command 要在终端中执行的命令
     * @return 命令执行的输出结果，若执行过程中出现错误，包含错误信息
     */
    @Tool(description = "Execute a command in the terminal")
    public String executeTerminalCommand(@ToolParam(description = "Command to execute in the terminal") String command) {
        // 用于存储命令执行的输出结果
        StringBuilder output = new StringBuilder();
        try {
            // 创建一个 ProcessBuilder 实例，指定在 Windows 命令提示符下执行命令
            // "cmd.exe" 表示使用 Windows 命令解释器，"/c" 表示执行完命令后关闭命令提示符
            ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", command);
            // 注释掉的代码：使用 Runtime.getRuntime().exec() 方法执行命令
            // 建议使用 ProcessBuilder 以获得更好的控制和灵活性
            // Process process = Runtime.getRuntime().exec(command);
            // 启动进程并执行命令
            Process process = builder.start();
            // 使用 BufferedReader 读取进程的输入流，即命令执行的输出信息
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                String line;
                // 逐行读取命令输出，直到没有更多内容
                while ((line = reader.readLine()) != null) {
                    // 将每行输出添加到 output 中，并添加换行符
                    output.append(line).append("\n");
                }
            }
            // 等待命令执行完成，并获取命令的退出码
            int exitCode = process.waitFor();
            // 若退出码不为 0，表示命令执行失败
            if (exitCode != 0) {
                // 将错误信息添加到 output 中
                output.append("Command execution failed with exit code: ").append(exitCode);
            }
        } catch (IOException | InterruptedException e) {
            // 捕获执行过程中可能出现的 IO 异常或线程中断异常
            // 将错误信息添加到 output 中
            output.append("Error executing command: ").append(e.getMessage());
        }
        // 返回命令执行的输出结果
        return output.toString();
    }
}
